package com.kehutong.tag.service;

import com.kehutong.common.entity.Root;
import com.kehutong.crm.enums.TagSourceType;
import com.kehutong.tag.dao.UserTagDao;
import com.kehutong.tag.entity.CustomizeTag;
import com.kehutong.tag.entity.OpinionTag;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.Condition;
import org.coraframework.orm.jdbc.execute.PageCondition;
import org.coraframework.orm.jdbc.execute.QueryCondition;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.IDGenerate;
import org.coraframework.util.Objects;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 舆情标签服务类
 *
 * @author: liukunlong
 * @date: 2021-07-28 10:08
 */
@WebService("/crm/opinion/tag/service")
public class OpinionTagService {

    static final Logger logger = LoggerFactory.getLogger(OpinionTagService.class);


    @Inject
    private JdbcSession jdbcSession;

    @Inject
    private UserTagDao userTagDao;


    /**
     * 根据条件获取标签列表
     *
     * @param jsonObject 查询对象
     * @return 标签列表
     * @throws IOException 操作异常
     */
    @ReqMapping("/page")
    public Page<OpinionTag> page(JSONObject jsonObject) throws Exception {
        String tagName = jsonObject.getString("tagName");

        Page<OpinionTag> result = null;
        FindPage<OpinionTag> findPage = jdbcSession.findPage(OpinionTag.class)
                .eq(jsonObject, "id", "pid")
                .like(jsonObject, "name")
                .eq("group", false)
                .eq("deleted", false)
                .order("sort", "desc")
                .page(jsonObject);
        result = findPage.exe();
        if (logger.isDebugEnabled()) {
            logger.debug("result:" + result);
        }
        if (Objects.nonNull(result)) {
            List<OpinionTag> opinionTagList = result.getList();
            //设置标签的标签组名称及使用标签用户数
            for (OpinionTag opinionTag : opinionTagList) {
                QueryCondition query = Condition.createQuery(false);
                query.eq("deleted", false);
                query.order("createTime","desc");
                query.eq("tagNo", opinionTag.getId());
                Map<String,Object> countMap = userTagDao.getUserTagCount(query);
                opinionTag.setUseCount(Long.parseLong(String.valueOf(countMap.get("count"))));
                OpinionTag opinionTagGroup = jdbcSession.findById(OpinionTag.class, opinionTag.getPid());
                if (Objects.nonNull(opinionTagGroup)) {
                    opinionTag.setPname(opinionTagGroup.getName());
                } else {
                    opinionTag.setPname("");
                }
            }
        }
        return result;
    }

    /**
     * 获取标签列表
     *
     * @param jsonObject 查询对象
     * @return
     * @throws Exception
     */
    @ReqMapping("/list")
    public Object list(JSONObject jsonObject) throws Exception {
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", Short.MAX_VALUE);
        Page<OpinionTag> page = page(jsonObject);
        return page.getList();
    }

    /**
     * 获取标签内容
     *
     * @param opinionTag 标签对象
     * @return
     */
    @ReqMapping("/get")
    public Object get(OpinionTag opinionTag) {
        return opinionTag;
    }

    /**
     * 保存标签
     *
     * @param opinionTag 系统标签对象
     * @return
     */
    @Bean(newInstance = true, copy = true)
    @ReqMapping("/save")
    public Object save(OpinionTag opinionTag) {
        String id = opinionTag.getId();
        OpinionTag dbOpinionTag = jdbcSession.findOne(OpinionTag.class)
                .eq("deleted", false)
                .eq("group", false)
                .markBegin()
                .eq("id", id).or()
                .eq("name", opinionTag.getName()).or()
                .markEnd().exe();
        opinionTag.setType(TagSourceType.OPINION_TAG);
        if (Objects.isNull(dbOpinionTag)) {
            opinionTag.setGroup(false);
            opinionTag.setSort(System.currentTimeMillis());
            opinionTag.setCreateBy(Root.ROOT_ID);
            opinionTag.setCreateName("系统");
            jdbcSession.insert(opinionTag);
        } else {
            dbOpinionTag.setName(opinionTag.getName());
            opinionTag.setCreateBy(Root.ROOT_ID);
            opinionTag.setCreateName("系统");
            jdbcSession.updateById(dbOpinionTag);
        }
        return Result.success();
    }

    /**
     * 更新标签组及标签
     *
     * @param opinionTag 系统标签对象
     * @return
     * @throws Exception
     */
    @Bean(copy = true)
    @ReqMapping("/update")
    public Object update(OpinionTag opinionTag) throws Exception {
        String id = opinionTag.getId();
        OpinionTag dbOpinionTag = jdbcSession.findOne(OpinionTag.class)
                .eq("group", false)
                .eq("deleted", false)
                .eq("id",id).exe();
        if (Objects.isNull(dbOpinionTag)) {
            return Result.success("0", "标签不存在");
        }
        jdbcSession.updateById(opinionTag);
        return Result.success();
    }


    /**
     * 删除标签
     *
     * @param opinionTag 标签对象
     * @return
     */
    @ReqMapping("/delete")
    public Object delete(OpinionTag opinionTag) {
        opinionTag.setDeleted(true);
        jdbcSession.updateById(opinionTag);
        return Result.success();
    }

    /**
     * 根据条件获取标签组分页列表
     *
     * @param jsonObject 查询对象
     * @return 住户汽车列表
     * @throws IOException 操作异常
     */
    @ReqMapping("/group/page")
    public Page<OpinionTag> groupPage(JSONObject jsonObject) throws Exception {
        String tagName = jsonObject.getString("tagName");

        Page<OpinionTag> result = null;
        FindPage<OpinionTag> findPage = jdbcSession.findPage(OpinionTag.class)
                .eq(jsonObject, "id")
                .like(jsonObject, "name")
                .eq("group", true)
                .eq("deleted", false)
                .order("sort", "desc")
                .page(jsonObject);
        if (Objects.nonEmpty(tagName)) {
            List<OpinionTag> opinionTagList = jdbcSession.findArray(OpinionTag.class)
                    .eq("group", false)
                    .eq("deleted", false)
                    .like("name", tagName).exe();
            List<String> ids = opinionTagList.stream().map(OpinionTag::getPid).collect(Collectors.toList());
            if (Objects.nonEmpty(ids)) {
                findPage.in("id", ids);
            }
        }
        result = findPage.exe();
        if (logger.isDebugEnabled()) {
            logger.debug("result:" + result);
        }
        if (Objects.nonNull(result)) {
            List<OpinionTag> opinionTagGroupList = result.getList();
            for (OpinionTag  opinionGroupTag : opinionTagGroupList) {
                List<OpinionTag> opinionTagList = jdbcSession.findArray(OpinionTag.class)
                        .eq("pid",  opinionGroupTag.getId())
                        .eq("group", false)
                        .eq("deleted", false)
                        .order("sort", "desc")
                        .exe();
                //设置标签的组名称
                for (OpinionTag opinionTag : opinionTagList) {
                    opinionTag.setPname( opinionGroupTag.getName());
                }
                opinionGroupTag.setChildList(opinionTagList);


            }
        }
        return result;
    }

    /**
     * 根据条件获取标签组列表
     *
     * @param jsonObject 查询对象
     * @return
     * @throws Exception
     */
    @ReqMapping("/group/list")
    public Object groupList(JSONObject jsonObject) throws Exception {
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", Short.MAX_VALUE);
        Page<OpinionTag> page = groupPage(jsonObject);
        return page.getList();
    }

    /**
     * 获取标签组
     *
     * @param opinionTagGroup 系统标签对象
     * @return
     */
    @ReqMapping("/group/get")
    public Object groupGet(OpinionTag opinionTagGroup) {
        if (Objects.nonNull(opinionTagGroup)) {
            List<OpinionTag> opinionTagList = jdbcSession.findArray(OpinionTag.class)
                    .eq("pid", opinionTagGroup.getId())
                    .eq("group", false)
                    .eq("deleted", false)
                    .order("sort", "desc")
                    .exe();
            opinionTagGroup.setChildList(opinionTagList);

        }
        return opinionTagGroup;
    }

    /**
     * 保存标气标签组及标签
     *
     * @param opinionTagGroup 系统标签对象
     * @return
     */
    @Bean(newInstance = true, copy = true)
    @ReqMapping("/group/save")
    public Object groupSave(OpinionTag opinionTagGroup) {
        String id = opinionTagGroup.getId();
        OpinionTag dbOpinionTagGroup = jdbcSession.findOne(OpinionTag.class)
                .eq("deleted", false)
                .eq("group", true)
                .markBegin()
                .eq("id", id).or()
                .eq("name", opinionTagGroup.getName()).or()
                .markEnd().exe();
        opinionTagGroup.setType(TagSourceType.OPINION_TAG);
        if (Objects.isNull(dbOpinionTagGroup)) {
            opinionTagGroup.setPid(Root.ROOT_ID);
            opinionTagGroup.setGroup(true);
            opinionTagGroup.setType(TagSourceType.OPINION_TAG);
            opinionTagGroup.setSort(System.currentTimeMillis());
            jdbcSession.insert(opinionTagGroup);
        } else {
            throw new RuntimeException("标签组不能重复");
/*            dbOpinionTagGroup.setName(opinionTagGroup.getName());
            jdbcSession.updateById(dbOpinionTagGroup);*/
        }
        List<OpinionTag> opinionTagList = opinionTagGroup.getChildList();
        if (Objects.nonNull(opinionTagList)) {
            for (OpinionTag opinionTag : opinionTagList) {
                opinionTag.setId(IDGenerate.uuid());
                opinionTag.setPid(opinionTagGroup.getId());
                opinionTag.setGroup(false);
                opinionTag.setType(TagSourceType.OPINION_TAG);
                opinionTag.setCreateBy(Root.ROOT_ID);
                opinionTag.setCreateName("系统");
            }
        }
        jdbcSession.insert(opinionTagList);
        return Result.success();
    }

    /**
     * 更新标签组及标签
     *
     * @param opinionTagGroup 系统标签对象
     * @return
     * @throws Exception
     */
    @Bean(copy = true)
    @ReqMapping("/group/update")
    public Object groupUpdate(OpinionTag opinionTagGroup) throws Exception {
        String id = opinionTagGroup.getId();
        OpinionTag dbOpinionTagGroup = jdbcSession.findOne(OpinionTag.class)
                .eq("deleted", false)
                .markBegin()
                .eq("id", id).or()
                .eq("name", opinionTagGroup.getName()).or()
                .markEnd().exe();
        if (Objects.isNull(dbOpinionTagGroup)) {
            return Result.success("0", "标签组不存在");
        }
        jdbcSession.updateById(opinionTagGroup);


        //输入的标签集合
        List<OpinionTag> opinionTagList = opinionTagGroup.getChildList();

        Map<String, OpinionTag> mapping = opinionTagList.stream().collect(Collectors.toMap(OpinionTag::getId, Function.identity()));


        //数据库已存在的标签集合
        List<OpinionTag> dbOpinionTagList = jdbcSession.findArray(OpinionTag.class)
                .eq("pid", dbOpinionTagGroup.getId())
                .eq("group", false)
                .eq("deleted", false)
                .order("sort", "desc")
                .exe();


        //需要更新的标签集合
        List<OpinionTag> updateOpinionTagList = new ArrayList<>();

        //需要删除的标签集合
        List<OpinionTag> deleteOpinionTagList = new ArrayList<>();

        for (OpinionTag dbOpinionTag : dbOpinionTagList) {
            String dbId = dbOpinionTag.getId();
            if (mapping.containsKey(dbId)) {
                updateOpinionTagList.add(mapping.get(dbId));
                opinionTagList.remove(dbOpinionTag);
            } else {
                deleteOpinionTagList.add(dbOpinionTag);
            }
        }

        //需要新增的标签集合
        List<OpinionTag> addOpinionTagList = new ArrayList<>(opinionTagList);

        //增量新增标签
        if (Objects.nonEmpty(addOpinionTagList)) {
            for (OpinionTag opinionTag : addOpinionTagList) {
                opinionTag.setId(IDGenerate.uuid());
                opinionTag.setPid(dbOpinionTagGroup.getId());
                opinionTag.setGroup(false);
                opinionTag.setType(TagSourceType.OPINION_TAG);
                opinionTag.setCreateBy(Root.ROOT_ID);
                opinionTag.setCreateName("系统");
            }
            jdbcSession.insert(addOpinionTagList);
        }

        //增量更新标签
        if (Objects.nonEmpty(updateOpinionTagList)) {
            jdbcSession.updateById(updateOpinionTagList);
        }

        //增量删除标签
        if (Objects.nonEmpty(deleteOpinionTagList)) {
            for (OpinionTag opinionTag : deleteOpinionTagList) {
                opinionTag.setDeleted(true);
            }
            jdbcSession.updateById(deleteOpinionTagList);
        }
        return Result.success();
    }


    /**
     * 删除标签组及标签
     *
     * @param opinionTagGroup 系统标签组对象
     * @return
     */
    @ReqMapping("/group/delete")
    public Object groupDelete(OpinionTag opinionTagGroup) {
        opinionTagGroup.setDeleted(true);
        jdbcSession.updateById(opinionTagGroup);
        if (opinionTagGroup.isGroup()) {
            List<OpinionTag> opinionTagList = jdbcSession.findArray(OpinionTag.class)
                    .eq("pid", opinionTagGroup.getId())
                    .eq("group", false)
                    .eq("deleted", false)
                    .order("sort", "desc")
                    .exe();
            if (Objects.nonEmpty(opinionTagList)) {
                for (OpinionTag opinionTag : opinionTagList) {
                    opinionTag.setDeleted(true);
                }
                jdbcSession.updateById(opinionTagList);
            }
        }
        return Result.success();
    }


}
